import React, {useState} from 'react';
import {DndContext, DragOverlay, closestCorners} from '@dnd-kit/core';
import {Draggable} from './Draggable';
import {Droppable} from './Droppable';
import {SortableItem} from './Sortable';

const boxs = [
  {id: 1, category: 'Apple', bg: 'red'},
  {
    id: 6, category: 'Peach', bg: 'pink', childrens: []
  },
];

const styleBox = {
  display: 'inline-block',
  margin: 20,
  padding: '16px 30px',
  width: 100,
  cursor: 'move',
  border: '1px solid'
};

const getRandomColor = function () {
  function colorFun(color) {
    return (color += '0123456789abcdef'[Math.floor(Math.random() * 16)])
    && (color.length === 6) ? color : colorFun(color);
  }

  return '#' + colorFun('');
};

function flatten(items, parentId = null, depth = 0) {
  return items?.reduce((acc, item, index) => {
    let children = [];
    if (Array.isArray(item.childrens)) {
      children = flatten(item.childrens, item.id, depth + 1);
    }
    return [
      ...acc,
      {...item, parentId, depth, index},
      ...children,
    ];
  }, []);
}

function findItem(items, itemId) {
  return items.find(({id}) => id === itemId);
}

function buildTree(flattenedItems) {
  const root = {id: 'root', childrens: []};
  const nodes = {[root.id]: root};

  for (const item of flattenedItems) {
    const {id, childrens} = item;
    const parentId = item.parentId ?? root.id;
    const parent = nodes[parentId] ?? findItem(flattenedItems, parentId);

    nodes[id] = {id, childrens};
    if (Array.isArray(parent.childrens)) {
      const a = parent.childrens.find(k => k.id === item.id);
      if (parent.childrens.length === 0 || !a) {
        parent.childrens.push(item);
      }
    }
  }

  return root.childrens;
}

function arrayMove(array, from, to) {
  const newArray = array.slice();
  newArray.splice(
    to < 0 ? newArray.length + to : to,
    0,
    newArray.splice(from, 1)[0]
  );

  return newArray;
}

function a(a1, a2) {
  console.log(a1);
  console.log(a2);
}

function Example() {
  const [parent, setParent] = useState([]);
  const [isDragging, setIsDragging] = useState(false);
  const Draggables = ({item}) => {
    return <Draggable id={item?.id} item={item}>
      {item?.category}
    </Draggable>;
  };

  return (
    <DndContext
      onDragOver={handleDragOver}
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
    >
      {
        boxs.map((k, i) => {
          return <Draggables item={k} key={i} index={i}>
            {k.category}
          </Draggables>;
        })
      }
      <Droppable id="droppable" item={parent}>
        {parent.map((k, i) => {
          return (
            <SortableItem item={k} key={i} id={k.id} index={i} activeIndex={isDragging}>
              {k.category}{k.id}
              {
                Array.isArray(k.childrens) && (
                  <Droppable id={k.category} item={k.childrens}>
                    {
                      k.childrens.map((j, l) => {
                        return (
                          <SortableItem item={j} key={l} id={j.id} index={l} parentIndex={i} activeIndex={isDragging}>
                            {j.category}{j.id}
                          </SortableItem>
                        );
                      })
                    }
                  </Droppable>
                )
              }
            </SortableItem>);
        })}
      </Droppable>
      <DragOverlay
        dropAnimation={null}
      >
        {isDragging ? (
          <div style={{...styleBox, backgroundColor: isDragging}}>
            box
          </div>
        ) : null}
      </DragOverlay>
    </DndContext>
  );

  function handleDragEnd(props) {
    const {active, over} = props;
    if (!over) return;
    // 节点容器
    let cloned = flatten(parent);
    // 扁平化根节点数组
    let clonedItems = JSON.parse(JSON.stringify(cloned));
    // 查找当前存放节点的数据
    let bePlaced = over.data.current?.parentIndex !== undefined ? clonedItems[over.data.current.parentIndex] : clonedItems.find(k => {
      return over.id === k.category && !over.data.current;
    });
    // 判断是否是根节点或者是子节点
    if (Array.isArray(bePlaced?.childrens)) clonedItems = bePlaced.childrens;
    // 初始化放置序号
    let overIndex = over?.data?.current?.index || 0;
    // 初始化拿取序号
    let activeIndex = active?.data?.current?.index;
    // 复制拿取数据
    let item = JSON.parse(JSON.stringify(active.data.current));
    // 判断是否是移动并不是新增
    if (typeof active.data.current.sortable === 'object') {
      clonedItems.splice(activeIndex, 1);
      item = JSON.parse(JSON.stringify(active.data.current.data));
    } else {
      item = JSON.parse(JSON.stringify(Object.assign(item, {id: isDragging})));
    }
    clonedItems.splice(overIndex, 0, item);
    if (Array.isArray(bePlaced?.childrens)) {
      bePlaced.childrens = clonedItems;
      cloned.splice(bePlaced.index || 0, 1, bePlaced);
    } else {
      cloned = clonedItems;
    }
    setParent(buildTree(cloned));
    setIsDragging(null);
  }

  function handleDragStart(props) {
    const {active} = props;
    let id = getRandomColor();
    if (active.data.current.sortable) {
      id = active.id;
    }
    setIsDragging(id);
  }

  function handleDragOver(props) {
    // console.log(props);
  }
}

export default Example;
